Skip to content

Bump matplotlib pin in tutorials to avoid Path.__deepcopy__ recursion - #10702

Merged
Light2Dark merged 3 commits into
marimo-team:mainfrom
afonsojanu:fix/tutorial-matplotlib-pin-savefig-recursion-10680
Sep 1, 2026
Merged

Bump matplotlib pin in tutorials to avoid Path.__deepcopy__ recursion#10702
Light2Dark merged 3 commits into
marimo-team:mainfrom
afonsojanu:fix/tutorial-matplotlib-pin-savefig-recursion-10680

Conversation

@afonsojanu

@afonsojanu afonsojanu commented Aug 29, 2026

Copy link
Copy Markdown

📝 Summary

Closes #10680

plots.py, dataflow.py, and markdown.py under marimo/_tutorials/ are pinned to matplotlib==3.10.1. That version hits an infinite recursion in Path.__deepcopy__ when _render_figure_mimebundle calls savefig(bbox_inches="tight"), which forces a full draw pass under marimo's sandboxed edit mode. The recursion happens because deepcopy's memo dict gets looked up via super() inside Path.__deepcopy__, and on the affected matplotlib version that lookup keeps recursing into itself instead of terminating.

The fix for that recursion landed upstream in matplotlib/matplotlib#30198, and 3.10.9 already carries it. sql.py in the same directory is already on 3.10.9 and has never hit this, which is what pointed me at the fix in the first place.

Bumping the three affected tutorials to matplotlib==3.10.9 to match.

📋 Pre-Review Checklist

  • For large changes, or changes that affect the public API: this change was discussed or approved through an issue, on Discord, or the community discussions. (See Plots tutorial doesn't work in --sandbox edit mode #10680, where this was reported and the fix was proposed and confirmed correct in the comments.)
  • Any AI generated code has been reviewed line-by-line by the human PR author, who stands by it.
  • Video or media evidence is provided for any visual changes (optional).

✅ Merge Checklist

  • I have read the contributor guidelines.
  • Documentation has been updated where applicable, including docstrings for API changes. (Not applicable, this is a dependency pin change with no API surface.)
  • Tests have been added for the changes made. (Not applicable, this is a version pin bump in tutorial scripts, not a code change with new logic to test.)

plots.py, dataflow.py, and markdown.py were pinned to matplotlib==3.10.1,
which hits an infinite recursion in Path.__deepcopy__ during
savefig(bbox_inches="tight") under marimo's sandboxed edit mode. The fix
for that landed upstream in matplotlib/matplotlib#30198; 3.10.9 already
carries it and is already used by sql.py in this same directory.

Fixes marimo-team#10680
Copilot AI lite review requested due to automatic review settings August 29, 2026 21:18
@vercel

vercel Bot commented Aug 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
marimo-docs Ready Ready Preview Sep 1, 2026 10:33am UTC

Request Review

@github-actions

github-actions Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the PEP 723 dependency pins for several built-in tutorials to avoid a matplotlib recursion bug triggered during figure rendering in --sandbox edit mode.

Changes:

  • Bump matplotlib pin from 3.10.1 to 3.10.9 in plots.py, dataflow.py, and markdown.py tutorial headers.
  • Align these tutorials’ matplotlib version with sql.py, which already uses 3.10.9.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
marimo/_tutorials/plots.py Updates tutorial dependency pin to matplotlib==3.10.9 to avoid the sandbox rendering recursion.
marimo/_tutorials/markdown.py Updates tutorial dependency pin to matplotlib==3.10.9 for consistency and to avoid the recursion.
marimo/_tutorials/dataflow.py Updates tutorial dependency pin to matplotlib==3.10.9 to avoid the sandbox rendering recursion.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 3 to 8
# requires-python = ">=3.12"
# dependencies = [
# "marimo",
# "matplotlib==3.10.1",
# "matplotlib==3.10.9",
# "numpy==2.2.4",
# "polars==1.26.0",
@afonsojanu

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

@Light2Dark

Copy link
Copy Markdown
Member

@afonsojanu , can you rewrite the PR description to follow our template. And have you manually verified the fix?

@Light2Dark
Light2Dark marked this pull request as draft September 1, 2026 07:02
@afonsojanu

Copy link
Copy Markdown
Author

Just updated the description to match the template, thanks for the nudge.

On verification: yes, I ran it manually rather than just going off the matplotlib changelog. Reproduced the actual crash first, running plots.py's savefig(bbox_inches="tight") path under matplotlib 3.10.1 gives the same RecursionError from Path.deepcopy described in #10680. Bumped just that one tutorial to 3.10.9 locally and confirmed it renders through without hitting the recursion. Also checked sql.py, which is already on 3.10.9 in this same directory and has a similar savefig path, to make sure that version doesn't reintroduce anything else.

I did not add a new automated test for it since the failure only shows up under marimo's sandboxed edit-mode rendering path, not a straightforward unit test target, and the existing tutorials already serve as the manual check for this kind of thing. Happy to look into a more targeted regression test if you'd rather have one before merging.

@Light2Dark

Copy link
Copy Markdown
Member

Just updated the description to match the template, thanks for the nudge.

On verification: yes, I ran it manually rather than just going off the matplotlib changelog. Reproduced the actual crash first, running plots.py's savefig(bbox_inches="tight") path under matplotlib 3.10.1 gives the same RecursionError from Path.deepcopy described in #10680. Bumped just that one tutorial to 3.10.9 locally and confirmed it renders through without hitting the recursion. Also checked sql.py, which is already on 3.10.9 in this same directory and has a similar savefig path, to make sure that version doesn't reintroduce anything else.

I did not add a new automated test for it since the failure only shows up under marimo's sandboxed edit-mode rendering path, not a straightforward unit test target, and the existing tutorials already serve as the manual check for this kind of thing. Happy to look into a more targeted regression test if you'd rather have one before merging.

Thats fine, thanks! We don't need tests for this. The copilot comment is correct, we should update other similar notebooks as well.

@afonsojanu
afonsojanu marked this pull request as ready for review September 1, 2026 10:12
markdown_format.md was flagged directly by review as still pinning
3.10.1 despite rendering a figure through the same savefig(bbox_inches=
tight) path fixed in the three tutorials already updated here. Checked
the rest of the repo for the same pin and found four more example
notebooks in the same boat (colliding_blocks_and_pi.py, plots.py,
multiple_definitions.py, multimodal_retrieval.py), so bumped all of
them to 3.10.9 to match what the rest of the repo already uses.
@afonsojanu

Copy link
Copy Markdown
Author

Went through the repo for the same pin and found four more affected: colliding_blocks_and_pi.py and multiple_definitions.py both return an Axes that gets rendered through the same savefig path, plots.py renders directly, and multimodal_retrieval.py imports matplotlib pinned there too even though it's currently unused (bumped it anyway for consistency). Pushed all four plus markdown_format.md to 3.10.9.

Light2Dark
Light2Dark previously approved these changes Sep 1, 2026

@Light2Dark Light2Dark left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

@Light2Dark Light2Dark added the bug Something isn't working label Sep 1, 2026
The dataflow.py bump to matplotlib 3.10.9 earlier in this branch never
made it into the markdown-conversion snapshot fixture, so
test_markdown_snapshots was failing on the old 3.10.1 pin baked into
dataflow.md.txt. Regenerated it against the current tutorial source.
@afonsojanu

Copy link
Copy Markdown
Author

@Light2Dark Thanks; I hope I’ve helped and that it gets merged. I hope my assistance has been beneficial.

@Light2Dark
Light2Dark enabled auto-merge (squash) September 1, 2026 10:37
@afonsojanu

afonsojanu commented Sep 1, 2026

Copy link
Copy Markdown
Author

@Light2Dark heads up on the one failing check (ubuntu-latest / Py 3.13 / core,optional deps): it's the two obstore tests in test_storage_models.py (TestObstoreIntegration::test_list_entries_with_memory_store and test_get_entry_with_memory_store), an e_tag quoting mismatch ('"0"' vs '0'), nothing to do with this PR. I checked and the same two tests were already failing on main this morning at 06:13 UTC, before any of my commits here, so it's a pre-existing issue unrelated to the matplotlib pin bumps.
Everything is fine on my end.

@Light2Dark
Light2Dark disabled auto-merge September 1, 2026 17:33
@Light2Dark
Light2Dark merged commit f9f475d into marimo-team:main Sep 1, 2026
55 of 57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plots tutorial doesn't work in --sandbox edit mode

3 participants